package com.example.zhu29.bledemo.util;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Base64;
import com.example.zhu29.bledemo.base.MyApplication;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * SharedPreferences Tools
 * Created by vondear on 2016/1/24.
 */

public class ZSPTool {

    private final static String JSON_CACHE = "JSON_CACHE";
    private static Context context;

    static {
        context = MyApplication.mInstance;
    }

    /**
     *Data stored in a custom ID can be approximated as a cache of network download data
     * Save in a single way
     *
     * @param tag    The tag of the stored content, the customary tag is named by the current class name to distinguish different   sp
     * @param content Deposited
     */
    public static void putContent(String tag, String content) {
        putString(tag, content);
    }

    /**
     * Get the storage named after the tag
     *
     * @param tag Named tag
     * @return Returns the content distinguished by tag, the default is empty
     */
    public static String getContent(String tag) {
        return getString(tag);
    }

    /**
     * SP Write in String Types of value
     *
     * @param key   key
     * @param value value
     */
    public static void putString(String key, String value) {
        SharedPreferences sp = context.getSharedPreferences(key, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString(key, value);
        editor.apply();
    }

    /**
     * Read String in SP
     *
     * @param key key
     * @return There is a return corresponding value, there is no return to the default value{@code defaultValue}
     */
    public static String getString(String key) {
        SharedPreferences sp = context.getSharedPreferences(key, Context.MODE_PRIVATE);
        String value;
        value = sp.getString(key, "");
        return value;
    }

    /**
     * Write int type value in SP
     *
     * @param key   key
     * @param value value
     */
    public static void putInt(String key, int value) {
        SharedPreferences sp = context.getSharedPreferences(key, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putInt(key, value);
        editor.apply();
    }

    /**
     * Read int in SP
     *
     * @param key key
     * @return There is a return corresponding value, there is no return to the default value -1
     */
    public static int getInt(String key) {
        SharedPreferences sp = context.getSharedPreferences(key, Context.MODE_PRIVATE);
        int value;
        value = sp.getInt(key, -1);
        return value;
    }

    /**
     * Write long type value in SP
     *
     * @param key   key
     * @param value value
     */
    public static void putLong(String key, long value) {
        SharedPreferences sp = context.getSharedPreferences(key, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putLong(key, value);
        editor.apply();
    }

    /**
     * Read long in SP
     *
     * @param key key
     * @return There is a return corresponding value, there is no return to the default value -1
     */
    public static long getLong(String key) {
        SharedPreferences sp = context.getSharedPreferences(key, Context.MODE_PRIVATE);
        long value;
        value = sp.getLong(key, -1L);
        return value;
    }

    /**
     * Write float type value in SP
     *
     * @param key   key
     * @param value value
     */
    public static void putFloat(String key, float value) {
        SharedPreferences sp = context.getSharedPreferences(key, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putFloat(key, value);
        editor.apply();
    }

    /**
     * Read float in SP
     *
     * @param key key
     * @return There is a return corresponding value, there is no return to the default value -1
     */
    public static float getFloat(String key) {
        SharedPreferences sp = context.getSharedPreferences(key, Context.MODE_PRIVATE);
        float value;
        value = sp.getFloat(key, -1F);
        return value;
    }

    /**
     * Write boolean type value in SP
     *
     * @param key   key
     * @param value value
     */
    public static void putBoolean(String key, boolean value) {
        SharedPreferences sp = context.getSharedPreferences(key, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putBoolean(key, value);
        editor.apply();
    }

    /**
     * Read boolean in SP
     *
     * @param key key
     * @return There is a return corresponding value, there is no return to the default value  {@code defaultValue}
     */
    public static boolean getBoolean(String key) {
        SharedPreferences sp = context.getSharedPreferences(key, Context.MODE_PRIVATE);
        boolean value;
        value = sp.getBoolean(key, false);
        return value;
    }

    /**
     * Read boolean in SP
     *
     * @param key key
     * @return There is a return corresponding value, there is no return to the default value {@code defaultValue}
     */
    public static boolean getBoolean(String key, boolean defaultVal) {
        SharedPreferences sp = context.getSharedPreferences(key, Context.MODE_PRIVATE);
        boolean value;
        value = sp.getBoolean(key, defaultVal);
        return value;
    }

    /**
     * Remove the key from the SP
     *
     * @param key key
     */
    public static void remove(String key) {
        SharedPreferences sp = context.getSharedPreferences(key, Context.MODE_PRIVATE);
        sp.edit().remove(key).apply();
    }


    /**
     * Store JSON cache data
     *
     * @param key     key
     * @param content content
     * @return
     */
    public static void putJSONCache(String key, String content) {
        SharedPreferences sp = context.getSharedPreferences(JSON_CACHE, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.putString(key, content);
        editor.apply();

    }

    /**
     * Read JSON cache data
     *
     * @param key key
     * @return
     */
    public static String readJSONCache(String key) {
        SharedPreferences sp = context.getSharedPreferences(JSON_CACHE, Context.MODE_PRIVATE);
        String jsoncache = sp.getString(key, null);
        return jsoncache;
    }


    /**
     * Clear specified information
     *
     * @param name Key name
     * @param key  If null, delete all key values under name
     */
    public static void clearPreference(String name, String key) {
        SharedPreferences sharedPreferences = context.getSharedPreferences(name, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        if (key != null) {
            editor.remove(key);
        } else {
            editor.clear();
        }
        editor.apply();
    }

    /**
     * writeObject The method is responsible for writing the state of an object of a particular class so that the corresponding readObject method can restore it.
     * Finally, use Base64.encode to convert the byte file to Base64 encoding and save it in String.
     *
     * @param object Object to be converted to a String to be encrypted
     * @return String   Encrypted String
     */
    private static String Object2String(Object object) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = null;
        try {
            objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(object);
            String string = new String(Base64.encode(byteArrayOutputStream.toByteArray(), Base64.DEFAULT));
            objectOutputStream.close();
            return string;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Use Base64 to decrypt the String and return the Object object.
     *
     * @param objectString String to be decrypted
     * @return object      Decrypted object
     */
    private static Object String2Object(String objectString) {
        byte[] mobileBytes = Base64.decode(objectString.getBytes(), Base64.DEFAULT);
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(mobileBytes);
        ObjectInputStream objectInputStream = null;
        try {
            objectInputStream = new ObjectInputStream(byteArrayInputStream);
            Object object = objectInputStream.readObject();
            objectInputStream.close();
            return object;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

    /**
     * Save objects using SharedPreference
     *
     * @param fileKey    Save the file's key
     * @param key        Store the object's key
     * @param saveObject Stored object
     */
    public static void saveObj(String fileKey, String key, Object saveObject) {
        SharedPreferences sharedPreferences = context.getApplicationContext().getSharedPreferences(fileKey, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        String string = Object2String(saveObject);
        editor.putString(key, string);
        editor.commit();
    }

    /**
     * Get the object saved by SharedPreference
     *
     * @param fileKey Save the file's key
     * @param key     Store the object's key
     * @return object Return the object obtained from the key
     */
    public static Object getObj(String fileKey, String key) {
        SharedPreferences sharedPreferences = context.getApplicationContext().getSharedPreferences(fileKey, Context.MODE_PRIVATE);
        String string = sharedPreferences.getString(key, null);
        if (string != null) {
            Object object = String2Object(string);
            return object;
        } else {
            return null;
        }
    }
}
